package cn.xuqiudong.console.module.system.service;

import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.common.base.service.BaseService;
import cn.xuqiudong.common.util.collections.CalcDiffCollection;
import cn.xuqiudong.common.util.encrypt.PasswordUtils;
import cn.xuqiudong.console.module.system.mapper.SysRoleMapper;
import cn.xuqiudong.console.module.system.mapper.SysUserMapper;
import cn.xuqiudong.console.module.system.model.SysRole;
import cn.xuqiudong.console.module.system.model.SysUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 系统用户表 Service
 *
 * @author Vic.xu
 */
@Service
public class SysUserService extends BaseService<SysUserMapper, SysUser> {

    @Resource
    private SysRoleMapper sysRoleMapper;

    /**
     * 保存用户 特殊处理下新增的时候新增默认密码 为用户名
     */
    @Override
    public int save(SysUser entity) {
        if (entity.getId() == null || entity.getId() <= 0) {
            entity.setPassword(PasswordUtils.entryptPassword(entity.getUsername()));
        }
        return super.save(entity);
    }

    /**
     * 根据用户名获取用心
     */
    public SysUser findUserByUsername(String username) {
        return mapper.findUserByUsername(username);
    }

    /**
     * 判断用户名是否重复
     */
    public boolean checkUsername(Integer id, String username) {
        return mapper.checkUsername(id, username);
    }

    /** 根据主键id查询对象 */
    @Override
    public SysUser findById(int id) {
        SysUser entity = mapper.findById(id);
        entity.setRoles(findUserRoles(id));
        return entity;
    }

    /**
     * 说明 :  用户拥有的角色
     * @author  Vic.xu
     * @since  2020年1月13日 上午9:40:21
     * @param id user id
     * @return roles
     */
    private List<SysRole> findUserRoles(Integer id) {
        return sysRoleMapper.findUserRoles(id);
    }

    /**
     * 说明 :  用户的权限
     * @author  Vic.xu
     * @since  2020年1月13日 上午9:43:12
     * @param id 用户id
     * @return 权限列表
     */
    private List<String> findUserPermissions(Integer id) {
        return sysRoleMapper.findUserPermissions(id);
    }

    /**
     * 保存用户以及他对应的角色
     *
     * @param entity user
     * @param roleIds roleIds
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUser entity, Integer[] roleIds) {
        save(entity);
        updateSysRoleRel(entity.getId(), roleIds);

    }

    /**
     * 说明 :  更新用户和角色的关系
     * @author  Vic.xu
     * @since  2020年1月13日 上午9:38:46
     * @param userId  userId
     * @param roles roles
     */
    private void updateSysRoleRel(Integer userId, Integer[] roles) {
        if (userId == null) {
            return;
        }
        if (roles == null || roles.length == 0) {
            mapper.deleteUserRoleByUserId(userId);
            return;
        }
        // 用户的已经拥有的角色
        List<Integer> oldRoleIds = mapper.userRoleIds(userId);

        CalcDiffCollection<Integer> calc = CalcDiffCollection.instance(oldRoleIds,
                new ArrayList<>(Arrays.asList(roles)));

        List<Integer> needAdd = calc.getOnlyInNew();
        List<Integer> needDel = calc.getOnlyInOld();
        // 新增角色和菜单关联
        if (!needAdd.isEmpty()) {
            mapper.addUserRole(userId, needAdd);
        }
        // 删除角色和菜单关联
        if (!needDel.isEmpty()) {
            mapper.deleteUserRole(userId, needDel);
        }
    }

    @Override
    protected boolean hasAttachment() {
        return true;
    }

    /**
     *
     * 说明 :  登陆操作
     * @author  Vic.xu
     * @since  2020年1月9日 上午11:00:39
     * @param username username
     * @param password password
     */
    public BaseResponse<String> login(String username, String password) {
        SysUser user = findUserByUsername(username);
        if (user == null) {
            return BaseResponse.error("不存在的用户");
        }
        if (!PasswordUtils.validatePassword(password, user.getPassword())) {
            return BaseResponse.error("密码错误");
        }
        //TODO after login
        return BaseResponse.success();
    }

}
